Fix PR#22427. The implementation of inplace_merge had a \'small data set\' optimization; if either half of the merge was small (i.e, less than 9 items), it did an inplace merge rather than allocating a buffer and doing a faster/smarter merge. However, this failed to satisfy the complexity requirements in the standard. Remove that code. Add tests to check the complexity, and add the same tests for std::merge, since we are in that section of the test suite anyway. git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@227811 91177308-0d34-0410-b5e6-96231b3b80d8 
diff --git a/include/algorithm b/include/algorithm index a179acf..9c51284 100644 --- a/include/algorithm +++ b/include/algorithm 
@@ -4482,12 +4482,6 @@  }  }   -template <class _Tp> -struct __inplace_merge_switch -{ - static const unsigned value = is_trivially_copy_assignable<_Tp>::value; -}; -  template <class _BidirectionalIterator, class _Compare>  inline _LIBCPP_INLINE_VISIBILITY  void @@ -4499,13 +4493,9 @@  difference_type __len1 = _VSTD::distance(__first, __middle);  difference_type __len2 = _VSTD::distance(__middle, __last);  difference_type __buf_size = _VSTD::min(__len1, __len2); - pair<value_type*, ptrdiff_t> __buf(0, 0); - unique_ptr<value_type, __return_temporary_buffer> __h; - if (__inplace_merge_switch<value_type>::value && __buf_size > 8) - { - __buf = _VSTD::get_temporary_buffer<value_type>(__buf_size); - __h.reset(__buf.first); - } + pair<value_type*, ptrdiff_t> __buf = _VSTD::get_temporary_buffer<value_type>(__buf_size); + unique_ptr<value_type, __return_temporary_buffer> __h(__buf.first); +  #ifdef _LIBCPP_DEBUG  typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;  __debug_less<_Compare> __c(__comp); 
diff --git a/test/std/algorithms/alg.sorting/alg.merge/inplace_merge_comp.pass.cpp b/test/std/algorithms/alg.sorting/alg.merge/inplace_merge_comp.pass.cpp index 8da8dfe..b54efb6 100644 --- a/test/std/algorithms/alg.sorting/alg.merge/inplace_merge_comp.pass.cpp +++ b/test/std/algorithms/alg.sorting/alg.merge/inplace_merge_comp.pass.cpp 
@@ -31,6 +31,7 @@  #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES    #include "test_iterators.h" +#include "counting_predicates.hpp"    template <class Iter>  void @@ -43,12 +44,14 @@  std::random_shuffle(ia, ia+N);  std::sort(ia, ia+M, std::greater<int>());  std::sort(ia+M, ia+N, std::greater<int>()); - std::inplace_merge(Iter(ia), Iter(ia+M), Iter(ia+N), std::greater<int>()); + binary_counting_predicate<std::greater<int>, int, int> pred((std::greater<int>())); + std::inplace_merge(Iter(ia), Iter(ia+M), Iter(ia+N), std::ref(pred));  if(N > 0)  {  assert(ia[0] == N-1);  assert(ia[N-1] == 0);  assert(std::is_sorted(ia, ia+N, std::greater<int>())); + assert(pred.count() <= (N-1));  }  delete [] ia;  } @@ -79,6 +82,7 @@  test_one<Iter>(3, 2);  test_one<Iter>(3, 3);  test<Iter>(4); + test<Iter>(20);  test<Iter>(100);  test<Iter>(1000);  } 
diff --git a/test/std/algorithms/alg.sorting/alg.merge/merge_comp.pass.cpp b/test/std/algorithms/alg.sorting/alg.merge/merge_comp.pass.cpp index 69bcaf1..bd38d7d 100644 --- a/test/std/algorithms/alg.sorting/alg.merge/merge_comp.pass.cpp +++ b/test/std/algorithms/alg.sorting/alg.merge/merge_comp.pass.cpp 
@@ -25,6 +25,7 @@  #include <cassert>    #include "test_iterators.h" +#include "counting_predicates.hpp"    template <class InIter1, class InIter2, class OutIter>  void @@ -41,12 +42,14 @@  ib[i] = 2*i+1;  std::reverse(ia, ia+N);  std::reverse(ib, ib+N); + binary_counting_predicate<std::greater<int>, int, int> pred((std::greater<int>()));  OutIter r = std::merge(InIter1(ia), InIter1(ia+N), - InIter2(ib), InIter2(ib+N), OutIter(ic), std::greater<int>()); + InIter2(ib), InIter2(ib+N), OutIter(ic), pred);  assert(base(r) == ic+2*N);  assert(ic[0] == 2*N-1);  assert(ic[2*N-1] == 0);  assert(std::is_sorted(ic, ic+2*N, std::greater<int>())); + assert(pred.count() <= (N + N - 1));  delete [] ic;  delete [] ib;  delete [] ia; @@ -63,12 +66,14 @@  std::copy(ic+N, ic+2*N, ib);  std::sort(ia, ia+N, std::greater<int>());  std::sort(ib, ib+N, std::greater<int>()); + binary_counting_predicate<std::greater<int>, int, int> pred((std::greater<int>()));  OutIter r = std::merge(InIter1(ia), InIter1(ia+N), - InIter2(ib), InIter2(ib+N), OutIter(ic), std::greater<int>()); + InIter2(ib), InIter2(ib+N), OutIter(ic), pred);  assert(base(r) == ic+2*N);  assert(ic[0] == 2*N-1);  assert(ic[2*N-1] == 0);  assert(std::is_sorted(ic, ic+2*N, std::greater<int>())); + assert(pred.count() <= (N + N - 1));  delete [] ic;  delete [] ib;  delete [] ia;